/*
    Speedbump aka Project Kimbula
    Copyright (C) 2010  Ping Shin Ching

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses.

	Ping Shin Ching
	righteous.ninja@gmail.com OR ping_sc@hotmail.com
	More information at http://www.tidytutorials.com/p/speedbump.html
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "protocolmanager.h"
#include "application.h"
#include "helpers.h"


/*************************************************************************
 * Constructor
 *************************************************************************/
ProtocolManager::ProtocolManager(){
	pmentry=0;
}


/*************************************************************************
 * Register a protocol against a port
 *************************************************************************/
short ProtocolManager::RegisterProtocolFactory(ProtocolHandlerFactoryInterface* fi, int portno, InitInterface* ii){
	ProtocolManagerEntry *pme = (ProtocolManagerEntry*)malloc(sizeof(ProtocolManagerEntry));
	
	pme->pcfacis =  fi;
	pme->PortNumber = portno;
	pme->param1 = fi->InitProtocolFactoyHanlder(ii);
	ntarrayadd((void***)&pmentry, sizeof(ProtocolManagerEntry*), pme, sizeof(*pme));
	free(pme);
	return 0;
}


/*************************************************************************
 * Get the protocol based on some initial data read from the socket
 *************************************************************************/
ProtocolHandlerInterface* ProtocolManager::GetProtocolHandler(const char* buf, unsigned int bufsize, ProtocolHandlerParams* php){
	for(int i = 0 ; pmentry[i]!=0 ; i++ ){
		//printf("checking protocol buffscan %s\n", pmentry[i]->pcfacis->GetProtocolName());
		if(pmentry[i]->pcfacis->CheckProtocol(buf, bufsize)){
			printf("Found protocol %s\n", pmentry[i]->pcfacis->GetProtocolName());
			if(php)
				php->param1 = pmentry[i]->param1;
			return pmentry[i]->pcfacis->GetHandler();
		}
	}
	return 0;
}


/*************************************************************************
 * Get the protocol based on the registered port
 *************************************************************************/
ProtocolHandlerInterface* ProtocolManager::GetProtocolHandler(int port, ProtocolHandlerParams* php){
	for(int i = 0 ; pmentry[i]!=0 ; i++ ){
		//printf("checking protocol port number %d against %s %d\n", port, pmentry[i]->pcfacis->GetProtocolName(),pmentry[i]->PortNumber);
		if(pmentry[i]->PortNumber == port){
			//printf("Found protocol %s\n", pmentry[i]->pcfacis->GetProtocolName());
			if(php)
				php->param1 = pmentry[i]->param1;
			return pmentry[i]->pcfacis->GetHandler();
		}
	}
	return 0;
}


/*************************************************************************
 * Destructor 
 *************************************************************************/
ProtocolManager::~ProtocolManager(){
	if(pmentry){
		for(int i = 0 ; pmentry[i]!=0 ; i++ ){
			delete pmentry[i]->pcfacis;
		}
		ntarraydestroy((void***)&pmentry);
	}
}
